home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume3 / uumail2 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  59.7 KB

  1. From: Stan Barber <genrad!neuro1!sob>
  2. Subject: uumail release 2
  3. Reply-To: sob@neuro1.UUCP (Stan Barber)
  4. Newsgroups: mod.sources
  5. Approved: jpn@panda.UUCP
  6.  
  7. Mod.sources:  Volume 3, Issue 68
  8. Submitted by: Stan Barber <genrad!neuro1!sob>
  9.  
  10.  
  11. This version of uumail contains all the fixes reported since
  12. the last release. Thanks to those that reported problems and
  13. especially those that sent along fixes or improvements.
  14.  
  15. This version also contains some improvements that I saw in
  16. the GATech Sendmail Configuration version of uumail to help
  17. uumail "know" when the database is being rebuilt. Please 
  18. be sure to read the README >ESPECIALLY IF YOU RUN A 
  19. DBM-formated database< ....
  20.  
  21. The next version of uumail will contain some more options
  22. to allow header munging and path optimization (I hope).
  23. If you already have some ideas or code that you'd like to
  24. donate to the cause, send it along.
  25.  
  26. Have a good holiday, or if this comes out in 1986, Have
  27. a good year.
  28.  
  29. #! /bin/sh
  30. # This is a shell archive, meaning:
  31. # 1. Remove everything above the #! /bin/sh line.
  32. # 2. Save the resulting text in a file.
  33. # 3. Execute the file with /bin/sh (not csh) to create the files:
  34. #    README
  35. #    makefile
  36. #    domains
  37. #    palias
  38. #    address.1
  39. #    address.c
  40. #    gethostnam.c
  41. #    getpath.c
  42. #    opath.3
  43. #    opath.c
  44. #    rmail.c
  45. #    uuconf.h
  46. #    uumail.1
  47. #    uumail.c
  48. #    uupath.1
  49. #    uupath.c
  50. # This archive created: Tue Dec 24 09:31:18 1985
  51. export PATH; PATH=/bin:$PATH
  52. echo shar: extracting "'README'" '(4023 characters)'
  53. if test -f 'README'
  54. then
  55.     echo shar: will not over-write existing file "'README'"
  56. else
  57. cat << \SHAR_EOF > 'README'
  58. This is an updated version of uumail (and uupath) that can 
  59. access a pathalias-generated database to facilitate routine mail.
  60.  
  61. These program can cope with DBM and standard line-oriented forms of 
  62. pathalias-generated databases.
  63.  
  64. This version of uumail can be used as uupath by linking uumail to
  65. uupath. Also, this version can handle domain addresses (user@host.domain).
  66. You can put as many addresses on a line as you like.
  67.  
  68. This version fixes a few bugs in the previous release. Some additional 
  69. functionality and robustness are added as well. The bugs included 
  70. lack of initilization of some variables in address.c, inconsistant calling
  71. of getpath in uumail, address and opath, and failure to handle % in addresses
  72. correctly. Additional features include  the ability of getpath to detect when
  73. the database is being updated and wait or abort as necessary, the ability to 
  74. retry accessing the database when it will not open (as might be the case when
  75. updating it), the ability (if the database is sorted) to search a plain-text
  76. database much faster.
  77.  
  78.  *    IF YOU ARE USING A DBM DATABASE, READ THIS!
  79.  *    If the special sentinel value of @@@ is not present in the
  80.  *    database, then getpath will assumed that the database is being
  81.  *    rebuilt and will block for TIMEOUT (default = 180) seconds.  
  82.  *    If, after 5 such blocks, the sentinel is not present,
  83.  *    the error code EX_TEMPFAIL is returned.
  84.  *    The same is true if the dbm files cannot be initialized.
  85.  *    Please be sure to add the sentinal to the DBM database when
  86.  *    it is created.
  87.  *
  88.  
  89. There are some compile flags to be aware of when making uumail.
  90. Here is a list of them.
  91.  
  92. DEBUG compiles in the debugging code.
  93. OPATH causes the opath subroutine to be used to resolve addresses.
  94. If you do not use this flag, you cannot use the user@host.domain style
  95. addresses with uumail.
  96. DBM causes uumail to use the DBM format patalias database. If you do not
  97. have the dbm libraries, do not use this flag.
  98. SYSIII will make adjustments for system that are derived from UNIX System
  99. III or System V.
  100. NOGRADE should be used if your uux does not understand the -g flag.
  101. NORETURN should be used if your uux does not understand the -a flag.
  102. LOG will enable logging of uumail traffic.
  103. UGLYUUCP causes the From_ line produced by uumail to contain the
  104. "remote from hostname" string.
  105. GETHOSTNAME will cause the system call gethostname to be used. If you
  106. are a BSD site, define this.
  107. SYSTEMNAME will cause the systemname to be derived from the file
  108. /usr/lib/uucp/SYSTEMNAME. This should be defined if your machine
  109. is a Sperry 5000.
  110. SORTED will cause the non-DBM database to be searched fasted, BUT
  111. it assumes that this database is SORTED. If you do not sort your
  112. database, do not define this.
  113.  
  114. If you want to install this system, use "make install". If you want
  115. to have it do all the work for incoming mail, type "make mailer". You
  116. probably do not want to "make mailer" if you run sendmail.
  117.  
  118. Here is the mailer segment of a sendmail configuration file that you
  119. can use to define the uumail program as a mailer.
  120. -------------------------------------------------------------------
  121. ############################################################
  122. #### This is a special mailer that takes advantage of    ###
  123. #### usemap database for addresses to UUCP sites         ###
  124. ############################################################
  125.  
  126. Muumail, P=/usr/lib/uucp/uumail,F=sDFhuUM,S=13,R=23,M=1000000,
  127.     A=uumail -h -gC -f$g $h!$u
  128. --------------------------------------------------------------
  129. Please be sure that the S= and R= rules are correct for your
  130. system. They should match the uucp mailer rules exactly.
  131.  
  132. A manual page for address, opath, uumail and uupath are included.
  133.  
  134. Please forward comments and bug fixes to me at sob@rice.edu or 
  135. ihnp4!shell!neuro1!sob or texsun!drilltech!sob
  136.  
  137. Stan Barber
  138. Baylor College of Medicine
  139. Houston, Texas
  140.  
  141. P.S. My thanks to all those who reported bugs from the previous release.
  142. Please continue to send them in, and I will try to keep fixing them.
  143. SHAR_EOF
  144. if test 4023 -ne "`wc -c < 'README'`"
  145. then
  146.     echo shar: error transmitting "'README'" '(should have been 4023 characters)'
  147. fi
  148. fi
  149. echo shar: extracting "'makefile'" '(3265 characters)'
  150. if test -f 'makefile'
  151. then
  152.     echo shar: will not over-write existing file "'makefile'"
  153. else
  154. cat << \SHAR_EOF > 'makefile'
  155. ####################################################################
  156. # makefile for uumail & uupath
  157. # program to integrate with pathalias created uucpmap databases
  158. # programs originally developed by Jeff Donnelly
  159. # updated to use pathalias database by Stan Barber
  160. # $Header: makefile,v 1.4 85/12/10 20:40:45 sob Exp $
  161. #
  162. # the following defines should be configured for you site
  163. # add -DDBM to CCFLAGS if your pathalias database used the
  164. # dbm(3) routines
  165. # if you are a ATT system III or system V site
  166. # or a masscomp add the -DSYSIII flags
  167. # If you want to use the opath subroutine to deal with
  168. # domain names add the -DOPATH flag to the CFLAGS line
  169. # you may want to modify the LIBS line to correspond to 
  170. # libraries that you may need at you site
  171. # see conf.h for other changes that may need be made
  172. # If you DO NOT use a DBM formatted database and would like to
  173. # get the best possible speed from uumail, add the -DSORTED
  174. # flag and be sure to sort your database
  175. # IMPORTANT INFORMATION ABOUT UUCP
  176. # If your uucp does not understand the -g (grade) flag
  177. # add the -DNOGRADE flag to CFLAGS.
  178. # If your uucp does not know about the -a (returnto) flag
  179. # add the -DNORETURN flag to CFLAGS
  180. # $Log:    makefile,v $
  181. # Revision 1.4  85/12/10  20:40:45  sob
  182. # Added install, mailer and all make options. Also defined BINDIR, UUCPDIR
  183. # and other useful things
  184. # Revision 1.3  85/08/03  00:38:33  UUCP
  185. # Added support for shar and RCS.
  186. # Changed name of gethostname to gethostnam to allow RCS to work right.
  187. # Stan Barber
  188. # Revision 1.2  85/07/11  19:28:52  sob
  189. # updated with gethostname.c
  190. # Revision 1.1  85/07/11  19:23:22  sob
  191. # Initial revision
  192. ###############################################################
  193. .SUFFIXES: .c,v .h,v
  194.  
  195. CFLAGS= -O -DSYSIII -DDEBUG -DOPATH -DUGLYUUCP -DLOG -DSORTED
  196.  
  197. LIBS=
  198.  
  199. BINDIR=/usr/lbin
  200.  
  201. UUCPDIR=/usr/lib/uucp
  202.  
  203. LIBDIR=/usr/lib
  204.  
  205. .c,v.c:
  206.     co -q $*.c
  207.  
  208. .h,v.h:
  209.     co -q $*.h
  210.  
  211. all: uumail rmail address
  212.  
  213. uumail: getpath.o uumail.o gethostnam.o opath.o
  214.     cc $(CFLAGS) getpath.o uumail.o gethostnam.o opath.o -o uumail $(LIBS)
  215.  
  216. address:address.o opath.o getpath.o
  217.     cc $(CFLAGS) address.o opath.o getpath.o -o address $(LIBS)
  218.  
  219. getpath.o: getpath.c uuconf.h
  220.  
  221. uupath.o: uupath.c uuconf.h
  222.  
  223. uumail.o: uumail.c uuconf.h
  224.  
  225. gethostnam.o:gethostnam.c
  226.  
  227. address.o:address.c
  228.  
  229. opath.o:opath.c
  230.  
  231. rmail: rmail.c gethostnam.o
  232.     cc $(CFLAGS) rmail.c gethostnam.o -o rmail $(LIBS)
  233.  
  234. install: uumail address domains palias
  235.     cp address $(BINDIR)
  236.     cp uumail domains palias $(UUCPDIR)
  237.     @echo "To install rmail in place of the current rmail, type"
  238.     @echo "make mailer"
  239.     ln $(UUCPDIR)/uumail $(BINDIR)/uupath
  240.  
  241. mailer: rmail
  242.     make install
  243.     rm -rf /bin/rmail
  244.     cp rmail /bin/rmail
  245.     
  246.  
  247. lint:
  248.     lint $(CFLAGS) getpath.c uumail.c gethostnam.c opath.c
  249.  
  250. clean: 
  251.     rm -f *.o *.CKP *.BAK *.bak
  252.  
  253. doc: uumail.1 uupath.1 address.1 opath.3
  254.     nroff -man uumail.1 >uumail.cat; nroff -man uupath.1 >uupath.cat; nroff -man address.1 >address.cat; nroff -man opath.3 >opath.cat
  255.  
  256. shar: domains palias rmail.c opath.c address.c uumail.c uuconf.h gethostnam.c uupath.c getpath.c README makefile uumail.1 uupath.1  opath.3 address.1
  257.     shar README domains palias rmail.c opath.c address.c uumail.c uuconf.h gethostnam.c uupath.c getpath.c makefile uumail.1 uupath.1  opath.3 address.1> shar.out
  258.  
  259. SHAR_EOF
  260. if test 3265 -ne "`wc -c < 'makefile'`"
  261. then
  262.     echo shar: error transmitting "'makefile'" '(should have been 3265 characters)'
  263. fi
  264. fi
  265. echo shar: extracting "'domains'" '(1093 characters)'
  266. if test -f 'domains'
  267. then
  268.     echo shar: will not over-write existing file "'domains'"
  269. else
  270. cat << \SHAR_EOF > 'domains'
  271. #
  272. # Domain Table
  273. #
  274. # Format: <domain>,<prefix>,<suffix>,<template>
  275. #
  276. # Where <template> may contain:
  277. #       %P - prefix string
  278. #       %S - suffix string
  279. #       %U - destination user name
  280. #       %N - destination site name
  281. #       %D - destination site name with domain suffix
  282. #       %% - a percent (%) sign
  283. #       %R - pathalias route to the destination site
  284. #
  285. .WA.UUCP,,,%R!%U
  286. .OR.UUCP,,,%R!%U
  287. .N-CA.UUCP,,,%R!%U
  288. .S-CA.UUCP,,,%R!%U
  289. .MTN.UUCP,,,%R!%U
  290. .S-CEN.UUCP,,,%R!%U
  291. .MID-W.UUCP,,,%R!%U
  292. .S-EAST.UUCP,,,%R!%U
  293. .ATL.UUCP,,,%R!%U
  294. .N-ENG.UUCP,,,%R!%U
  295. .HI.UUCP,,,%R!%U
  296. .W-CAN.UUCP,,,%R!%U
  297. .E-CAN.UUCP,,,%R!%U
  298. .EUR.UUCP,,,%R!%U
  299. .UK.UUCP,,,%R!%U
  300. .AUS.UUCP,,,%R!%U
  301. .ISRAEL.UUCP,,,%R!%U
  302. .ATT.UUCP,>ihnp4,,%P!%D!%U
  303. .HP.UUCP,,,%R!%U
  304. .PE.UUCP,,,%R!%U
  305. .UUCP,,,%R!%U
  306. .CSNET,>rice,,%P!%U%%%D@CSNET-RELAY.ARPA
  307. .MAILNET,>rice,,%P!%U%%%D@MULTICS.MIT.EDU
  308. # .BITNET,>rice,,%P!%U%%%D@WISCVM.ARPA
  309. .XEROX,>rice,,%P!%U.%D@XEROX.ARPA
  310. .DEC,>decwrl,,%P!%U@%D
  311. .ARPA,>rice,,%P!%U@%D
  312. .EDU,>rice,,%P!%U@%D
  313. .COM,>rice,,%P!%U@%D
  314. .GOV,>rice,,%P!%U@%D
  315. .MIL,>rice,,%P!%U@%D
  316. .OTH,>rice,,%P!%U@%D
  317. .BITNET,>psuvax,,%P!%U@%D
  318. SHAR_EOF
  319. if test 1093 -ne "`wc -c < 'domains'`"
  320. then
  321.     echo shar: error transmitting "'domains'" '(should have been 1093 characters)'
  322. fi
  323. fi
  324. echo shar: extracting "'palias'" '(151 characters)'
  325. if test -f 'palias'
  326. then
  327.     echo shar: will not over-write existing file "'palias'"
  328. else
  329. cat << \SHAR_EOF > 'palias'
  330. baylor baylor!%s
  331. decwrl shell!ihnp4!decwrl!%s
  332. ihnp4 shell!ihnp4!%s
  333. kitty baylor!kitty!%s
  334. neuro1 %s
  335. psuvax shell!psuvax!%s
  336. rice  rice!%s
  337. shell shell!%s
  338. SHAR_EOF
  339. if test 151 -ne "`wc -c < 'palias'`"
  340. then
  341.     echo shar: error transmitting "'palias'" '(should have been 151 characters)'
  342. fi
  343. fi
  344. echo shar: extracting "'address.1'" '(3589 characters)'
  345. if test -f 'address.1'
  346. then
  347.     echo shar: will not over-write existing file "'address.1'"
  348. else
  349. cat << \SHAR_EOF > 'address.1'
  350. .TH ADDRESS 1 local
  351. .SH NAME
  352. address - display the path generated by \fBdeliver\fR for an
  353. RFC822-format address.
  354. .SH SYNOPSIS
  355. address rfc-address [ ... ]
  356. .SH DESCRIPTION
  357. This program allows you to check the UUCP mail routing path that will
  358. be generated by the UUCP mailer \fBdeliver\fR if you specify an
  359. RFC822-format address \fBrfc-address\fR in the ``To:'' field of the mail header.
  360. For each RFC-style address on the command line, \fBaddress\fR echoes the
  361. address to the standard output, followed by a colon, followed by
  362. the UUCP address that will be used to send the message to that address.
  363.  
  364. .SH "ADDRESS FORMAT"
  365. Briefly, the RFC822-format address is of the form
  366. .nf
  367. .sp 1
  368.     <localaddress>@<hostname>.<network>
  369. .sp 1
  370. .fi
  371. where <hostname> is the name of the system you are sending the message
  372. to, <network> is a modifier for <hostname> identifying the network in
  373. which the address is to be interpreted (UUCP, ARPA, MAILNET, CSNET, etc);
  374. and <localaddress> is an address string to be interpreted on the host
  375. machine.
  376.  
  377. The <localaddress> field may contain further remote addresses to be
  378. interpreted on the host machine.  Typically this will be an address for
  379. mailing via another network; and in particular, the <localaddress> may
  380. (recursively) be identical in format to the RFC address, but with
  381. the symbol `%' replacing the symbol `@' in the standard address format.
  382. Where this form is used, the rightmost % is replaced by an
  383. @ before the host machine sends the message out.
  384.  
  385. On our system, the presently
  386. valid <network>s are UUCP, ARPA, CSNET, and MAILNET.
  387. The recently proposed UUCP domain names are also accepted, although
  388. they are treated the same as plain ``UUCP''.
  389. Omitting
  390. the <network> causes the network to default to UUCP.  The <hostname>
  391. should be the name of a remote machine to which the message is
  392. directed; see \fI/usr/lib/uucp/uuaddress.alpha\fR for a list of all
  393. known UUCP hostnames.  It is \fInot\fR necessary to specify a UUCP pathname
  394. when using this format; the pathname is automatically determined for you
  395. and substituted into the address before mailing.  The selected pathname
  396. is determined using the \fBpathalias\fR database, and is supposed
  397. to be optimal, taking into consideration information provided by
  398. each site about how often they send mail out, etc.
  399.  
  400. .SH EXAMPLES
  401. .HP 5
  402. joe
  403. .br
  404. The message is sent to the user ``joe'' on the local system.
  405. .HP 5
  406. joe@ucbvax
  407. .br
  408. The message is sent to joe on the UUCP system named ``ucbvax''; this
  409. address is automatically translated to a proper (and ostensibly
  410. optimal) UUCP path.
  411. .HP 5
  412. joe@ucbvax.UUCP
  413. .br
  414. Same as joe@ucbvax
  415. .HP 5
  416. joe@ucbvax.ARPA
  417. .br
  418. The message is addressed to joe at ucbvax, using the ARPA network.
  419. The message will be routed to the ARPAnet via a UUCP-ARPAnet gateway.
  420. .HP 5
  421. joe%mit-multics.ARPA@ucbvax
  422. .br
  423. The message is sent to ucbvax, who then uses the address
  424. joe@mit-multics.ARPA to send the message on to mit-multics via the
  425. ARPAnet.  Since ucbvax is on the arpanet, this address will work correctly
  426. (as long as there is someone named joe on the MIT multics machine).
  427. .HP 5
  428. joe%vanderbilt.MAILNET%mit-multics.ARPA@ucbvax
  429. .br
  430. The message is sent via UUCP to ucbvax, who then sends the message
  431. to mit-multics via the arpanet; mit-multics then sends the message
  432. to joe@vanderbilt via MAILNET.  Since the above machines each have access
  433. to the networks named in the address, this address will work correctly.
  434. .SH FILES
  435. /usr/lib/uucp/domains - Domain/gateway table
  436. .br
  437. /usr/lib/uucp/palias - Pathalias database
  438. .SH "SEE ALSO"
  439. opath(3), uupath(1), uumail(8)
  440. .SH AUTHOR
  441. Eric Roskos, CONCURRENT COMPUTERS
  442. SHAR_EOF
  443. if test 3589 -ne "`wc -c < 'address.1'`"
  444. then
  445.     echo shar: error transmitting "'address.1'" '(should have been 3589 characters)'
  446. fi
  447. fi
  448. echo shar: extracting "'address.c'" '(1035 characters)'
  449. if test -f 'address.c'
  450. then
  451.     echo shar: will not over-write existing file "'address.c'"
  452. else
  453. cat << \SHAR_EOF > 'address.c'
  454. /*
  455.  * address - run opath to see what a translated RFC822 address will come
  456.  * out as.
  457.  *
  458.  * By E. Roskos 1/16/85
  459.  * $Log:    address.c,v $
  460.  * Revision 1.3  85/11/24  14:50:01  sob
  461.  * Added corrections provided by regina!mark
  462.  * 
  463.  * Revision 1.2  85/09/16  18:31:53  sob
  464.  * Added DEBUG flag
  465.  * 
  466.  * Revision 1.1  85/09/16  17:50:24  sob
  467.  * Initial revision
  468.  * 
  469.  */
  470. #define _DEFINE
  471. #include "uuconf.h"
  472.  
  473. static char rcsid[] = "$Header: address.c,v 1.3 85/11/24 14:50:01 sob Exp $";
  474.  
  475. EXTERN char *paths;
  476. char *opath();
  477. int Debug;
  478.  
  479. main(argc,argv)
  480. int argc;
  481. char **argv;
  482. {
  483. char *p;
  484. int uswitch;
  485.  
  486. paths = DATABASE;
  487. ConfFile=CONFIGFILE;
  488.  
  489.     if (argc < 2)
  490.     {
  491.         fprintf(stderr,"usage: %s rfcaddress [...]\n",
  492.             argv[0]);
  493.         exit(1);
  494.     }
  495.  
  496.     while (--argc)
  497.     {
  498.         p = *++argv;
  499.         if (*p=='-')
  500.         {
  501.             switch(*++p)
  502.             {
  503.             case 'u': uswitch++;
  504.                   continue;
  505.             case 'd': Debug++;
  506.                       continue;
  507.             default:  printf("unknown switch: %c\n",*p);
  508.                   continue;
  509.             }
  510.             continue;
  511.         }
  512.         printf("%s: %s\n",p,uswitch?oupath(p):opath(p));
  513.     }
  514.  
  515.     exit(0);
  516. }
  517. SHAR_EOF
  518. if test 1035 -ne "`wc -c < 'address.c'`"
  519. then
  520.     echo shar: error transmitting "'address.c'" '(should have been 1035 characters)'
  521. fi
  522. fi
  523. echo shar: extracting "'gethostnam.c'" '(1372 characters)'
  524. if test -f 'gethostnam.c'
  525. then
  526.     echo shar: will not over-write existing file "'gethostnam.c'"
  527. else
  528. cat << \SHAR_EOF > 'gethostnam.c'
  529. #ifndef lint
  530. static char    sccsid[] = "@(#)gethostnam.c    6.1 (down!honey) 85/01/21";
  531. static char    rcsid[] = "$Header: gethostnam.c,v 6.3 85/11/23 05:30:04 UUCP Exp $";
  532. #endif lint
  533.  
  534. #ifndef GETHOSTNAME
  535. #include "uuconf.h"
  536.  
  537. void
  538. gethostname(name, len)
  539. char    *name;
  540. {
  541.     FILE    *whoami, *fopen(), *popen();
  542.     char    *ptr, *index();
  543. #if defined(SYSIII) && !defined(SYSTEMNAME)
  544.     struct utsname utsn;
  545. #endif
  546.  
  547.     *name = '\0';
  548. #ifndef SYSTEMNAME
  549. #ifdef SYSIII
  550.     if (uname(&utsn) != -1)
  551.     {
  552.         strcpy(name,utsn.nodename);
  553.         len = strlen(name);
  554.           return;
  555.     }
  556. #endif
  557. #endif
  558.  
  559. #ifdef SYSTEMNAME
  560.     /* try /usr/lib/uucp/SYSTEMNAME */
  561.     if ((whoami = fopen("/usr/lib/uucp/SYSTEMNAME", "r")) != 0) {
  562.         (void) fgets(name, len, whoami);
  563.         (void) fclose(whoami);
  564.         if ((ptr = index(name, '\n')) != 0)
  565.             *ptr = '\0';
  566.     }
  567.     if (*name)
  568.         return;
  569. #endif
  570.     /* try /usr/include/whoami.h */
  571.     if ((whoami = fopen("/usr/include/whoami.h", "r")) != 0) {
  572.         while (!feof(whoami)) {
  573.             char    buf[100];
  574.  
  575.             if (fgets(buf, 100, whoami) == 0)
  576.                 break;
  577.             if (sscanf(buf, "#define sysname \"%[^\"]\"", name))
  578.                 break;
  579.         }
  580.         (void) fclose(whoami);
  581.         if (*name)
  582.             return;
  583.     }
  584.  
  585.     /* ask uucp */
  586.     if ((whoami = popen("uuname -l", "r")) != 0) {
  587.         (void) fgets(name, len, whoami);
  588.         (void) pclose(whoami);
  589.         if ((ptr = index(name, '\n')) != 0)
  590.             *ptr = '\0';
  591.     }
  592.     if (*name)
  593.         return;
  594.     
  595.     /* failure */
  596.     return;
  597. }
  598. #endif GETHOSTNAME
  599. SHAR_EOF
  600. if test 1372 -ne "`wc -c < 'gethostnam.c'`"
  601. then
  602.     echo shar: error transmitting "'gethostnam.c'" '(should have been 1372 characters)'
  603. fi
  604. fi
  605. echo shar: extracting "'getpath.c'" '(6606 characters)'
  606. if test -f 'getpath.c'
  607. then
  608.     echo shar: will not over-write existing file "'getpath.c'"
  609. else
  610. cat << \SHAR_EOF > 'getpath.c'
  611. /*
  612.  * Name: getpath -- return the full usenet path of the given name
  613.  *
  614.  * Paramaters: sysname (input) -- The system name to be expanded
  615.  *           pathname (output)  The usenet path of the given system name
  616.  *           pathfile (input) the file to search for the system name
  617.  *
  618.  * Returns: EX_OK     -- path found
  619.  *        EX_NOHOST -- path not found
  620.  *        EX_NOINPUT-- unable to open usemap
  621.  *          EX_TEMPFAIL -- database being rebuilt
  622.  *
  623.  * Author: J. Donnelly   3/82
  624.  *
  625.  */
  626.  
  627. /*    IF YOU ARE USING A DBM DATABASE, READ THIS!
  628.  *    If the special sentinel value of @@@ is not present in the
  629.  *    database, then it is assumed that the database is being
  630.  *    rebuilt and the requesting process is blocked for TIMEOUT
  631.  *    (default = 180) seconds.  If, after 5 such blocks, the
  632.  *    sentinel is not present, the error code EX_TEMPFAIL is returned.
  633.  *    The same is true if the dbm files cannot be initialized.
  634.  */
  635.  
  636. /* 22-jun-83 Sheppard
  637.  * modified to rewind path file (if open), rather than open again
  638.  *
  639.  * $Log:    getpath.c,v $
  640.  * Revision 1.14  85/12/13  15:23:21  sob
  641.  * Added patches from umd-cs!steve
  642.  * 
  643.  * Revision 1.13  85/12/10  20:36:58  sob
  644.  * Added modifications suggested in gatech's version of uumail.
  645.  * Now, the DBM version of the database needs to have a SENTINAL in it
  646.  * to indicate that the DATABASE is not being updated. Also added similiar
  647.  * indicators to the non-DBM version to compare modification times and act
  648.  * accordingly. 
  649.  * 
  650.  * Revision 1.12  85/12/02  15:48:39  sob
  651.  * Combined speed hacks and old way of reading database and
  652.  * added compile flag SORTED. If database is SORTED and not DBM, use
  653.  * -DSORTED in CFLAGS to make it fast. If database is not sorted
  654.  * DO NOT use this flag.
  655.  * 
  656.  * Revision 1.11  85/11/24  15:03:41  sob
  657.  * Added changes suggested by regina!mark
  658.  * 
  659.  * Revision 1.10  85/11/24  04:21:45  sob
  660.  * Added efficiency hacks supplied by meccts!asby (Shane P. McCarron)
  661.  * 
  662.  * Revision 1.9  85/11/14  20:21:49  sob
  663.  * Added #ifdef DEBUG to allow compilation without DEBUG
  664.  * 
  665.  * Revision 1.8  85/11/08  03:04:49  sob
  666.  * release version
  667.  * 
  668.  * Revision 1.7  85/09/30  02:47:40  sob
  669.  * Altered to use path filename from global variable.
  670.  * 
  671.  * Revision 1.6  85/08/03  00:48:57  UUCP
  672.  * Cleaned up with lint.
  673.  * Stan Barber
  674.  * 
  675.  * Revision 1.5  85/07/19  17:45:13  UUCP
  676.  * Added \t as a valid seperation character for the database
  677.  * in the non DBM case. This is what pathalias uses.
  678.  * 
  679.  * Revision 1.4  85/07/19  16:44:07  UUCP
  680.  * revised to return proper things in accordance with sysexits
  681.  * Stan
  682.  * 
  683.  * Revision 1.3  85/07/11  19:30:31  sob
  684.  * added "uuconf.h" include file and deleted duplicated information
  685.  * 
  686.  * Revision 1.2  85/07/10  18:30:59  sob
  687.  * updated to add DBM capabilities
  688.  * Stan Barber, Baylor College of Medicine
  689.  * 
  690.  * Revision 1.1  85/07/10  18:03:28  sob
  691.  * Initial revision
  692.  * 
  693.  */
  694.  
  695. #include    "uuconf.h"
  696. #ifndef DBM
  697. #include <sys/types.h>
  698. #include <sys/stat.h>
  699. #endif
  700.  
  701. static char rcsid[] = "$Header: getpath.c,v 1.14 85/12/13 15:23:21 sob Exp $";
  702.  
  703. FILE * fopen (), *in;
  704.  
  705. int getpath (sysname, pathname,pathfile)
  706. char   *sysname, *pathname,*pathfile;
  707. {
  708.     int retval,indx;
  709. #ifdef DBM
  710.     datum lhs,rhs;
  711. #else
  712.     struct stat st;
  713.         time_t modtime;
  714. #ifdef SORTED
  715.     int scomp();
  716.  
  717.     long lo,hi;
  718.     long cur;
  719.     long last;
  720.     static char buf[256];
  721. #else
  722.     char    name[NAMESIZ],*p,t;
  723. #endif
  724. #endif
  725.  
  726. #ifdef DEBUG
  727. if (Debug>2)
  728.     printf("In getpath: Sysname = %s, Pathfile = %s\n",sysname,paths);
  729. #endif
  730.  
  731. #ifdef DBM
  732.     for (indx = 0; indx < 5; indx++)
  733.     {
  734.     if ((retval = dbminit (pathfile)) >= 0)
  735.         break;
  736.     
  737. #ifdef DEBUG
  738.     if (Debug>2)
  739.         fprintf (stderr, "Database unavailable.  Sleeping.\n");
  740. #endif
  741.     sleep (TIMEOUT);
  742.     }
  743.  
  744.     if (retval < 0)
  745.     return(EX_NOINPUT);
  746.  
  747.     lhs.dptr = SENTINEL;
  748.     lhs.dsize = strlen (SENTINEL) + 1;
  749.     for (indx = 0; indx < 5; indx++)
  750.     {
  751.     rhs = fetch (lhs);
  752.     if (rhs.dsize > 0)
  753.         break;
  754.     
  755. #ifdef DEBUG
  756.     if (Debug>2)
  757.         fprintf (stderr, "Database incomplete.  Sleeping.\n");
  758. #endif
  759.     sleep (TIMEOUT);
  760.     }
  761.     if (rhs.dsize <= 0)
  762.     return(EX_TEMPFAIL);
  763.  
  764.         lhs.dptr = sysname;
  765.     lhs.dsize = strlen(sysname)+1;
  766.     rhs = fetch(lhs);
  767.     if (rhs.dptr == NULL) return(EX_NOHOST); /* no name found */
  768.     strcpy(pathname,rhs.dptr);
  769.         return(EX_OK);            /* system name found */
  770.  
  771. #else
  772. if (in == NULL) 
  773.     {
  774.     for (indx = 0; indx < 5; indx++)
  775.         {
  776.         if ((in = fopen(pathfile, "r")) != NULL)
  777.             break;
  778.     
  779. #ifdef DEBUG
  780.         if (Debug>2)
  781.             fprintf (stderr, "Database unavailable.  Sleeping.\n");
  782. #endif
  783.         sleep (TIMEOUT);
  784.         }
  785.     if (in == NULL)
  786.     return(EX_NOINPUT);
  787.     }
  788.     else
  789.     rewind(in);
  790.     indx = 0;
  791. restart:
  792.     indx++;
  793.     if (indx > 5) return(EX_TEMPFAIL);
  794.     stat(pathfile, &st);
  795.     modtime=st.st_mtime; /* original last modification time */
  796.  
  797. #ifdef SORTED
  798.     lo = 0;
  799.     hi = st.st_size;
  800.     last = 0;
  801.     cur = hi >> 1;
  802.  
  803.     while (cur > lo && cur < hi)
  804.     {
  805.         stat(pathfile,&st);
  806.         if (st.st_mtime > modtime) goto restart;
  807.         fseek(in, cur, 0);
  808.         fgets(buf, sizeof(buf), in);
  809.         cur = ftell(in);
  810.         fgets(buf, sizeof(buf), in);
  811.  
  812. #ifdef    DEBUG
  813.     if (Debug > 4)
  814.         printf("Found site %s\n", buf);
  815. #endif
  816.         if (scomp(sysname, buf) < 0) hi = cur;
  817.         else
  818.         if (scomp(sysname, buf) > 0) lo = cur;
  819.         else
  820.         {
  821.             buf[strlen(buf)-1] = '\0';
  822.             strcpy(pathname, (char *)index(buf, '\t') + 1);
  823.             return(EX_OK);
  824.         }
  825.         cur = lo + ((hi - lo)>>1);
  826.         if (last == cur) 
  827.         {
  828.             fseek(in, lo, 0);
  829.             do
  830.             {
  831.                 fgets(buf, sizeof(buf), in);
  832.                 lo = ftell(in);
  833.                 if (scomp(sysname, buf) == 0)
  834.                 {
  835.                     buf[strlen(buf)-1] = '\0';
  836.                     strcpy(pathname, (char *)index(buf, '\t') + 1);
  837.                     return(EX_OK);
  838.                 }
  839.             } while (lo <= hi);
  840.             break;
  841.         } /* end if */
  842.         last = cur;
  843.     } /* end while */
  844.     return(EX_NOHOST);
  845. #else
  846.  
  847.     for (;;)
  848.     {
  849.     p = &name[0];
  850.     while ((t = getc(in)) != EOF && (*p++ = t) != ' ' && t != '\t'); /* read the system name */
  851.         stat(pathfile,&st);
  852.         if (st.st_mtime > modtime) goto restart;        /* database update in progress */
  853.     if( t == EOF) return(EX_NOHOST);
  854.     *--p = '\0';                    /* set end of string */
  855.     p = &name[0];
  856. #ifdef DEBUG
  857.     if (Debug>4) printf("Found %s\n",p);
  858. #endif
  859.     if (strcmp (p,sysname) == 0)
  860.         break;
  861.     while ((getc (in) != '\n'));            /* skip this path */
  862.     }
  863.     p = pathname;                    /* save start loc of pathname */
  864.     while ((*pathname++ = getc (in)) != '\n');
  865.     *--pathname = '\0';
  866.     pathname = p;
  867.     return(EX_OK);            /* system name found */
  868.  
  869. #endif
  870. #endif
  871. }
  872.  
  873. #ifdef    SORTED
  874. #define MAPTAB(c) ((c=='\t')?'\0':c)
  875.  
  876. int scomp(a,b)
  877. char *a,*b;
  878. {
  879. int r;
  880.     while (!(r=(MAPTAB(*a)-MAPTAB(*b))) && *a && *b && *a!='\t' && *b!='\t')
  881.     {
  882.            a++; b++;
  883.     }
  884.     return(r);
  885. }
  886. #endif
  887. SHAR_EOF
  888. if test 6606 -ne "`wc -c < 'getpath.c'`"
  889. then
  890.     echo shar: error transmitting "'getpath.c'" '(should have been 6606 characters)'
  891. fi
  892. fi
  893. echo shar: extracting "'opath.3'" '(4889 characters)'
  894. if test -f 'opath.3'
  895. then
  896.     echo shar: will not over-write existing file "'opath.3'"
  897. else
  898. cat << \SHAR_EOF > 'opath.3'
  899. .TH OPATH 3 "CONCURRENT"
  900. .SH NAME
  901. opath - Generate a UUCP route from an RFC822 address
  902. .br
  903. oupath - Generate a UUCP route from a (possibly disconnected) UUCP path
  904. .SH SYNOPSIS
  905. char *opath(s)
  906. .br
  907. char *s;
  908. .sp 1
  909. char *oupath(s)
  910. .br
  911. char *s;
  912. .SH DESCRIPTION
  913. These routines use the \fBpathalias\fR database to generate UUCP routing
  914. paths from your local site to specified remote sites on either the UUCP
  915. network or other connected networks.
  916. .PP
  917. \fBopath\fR takes one argument, an RFC822 address, as described in
  918. ADDRESS(1).  From this, it generates and returns a UUCP path to the site
  919. named in the argument.
  920. .PP
  921. \fBoupath\fR takes one argument, a UUCP path.  If the next site on this
  922. path is named \fIx\fR, \fBoupath\fR will prepend a path from your site to
  923. \fIx\fR, if \fIx\fR is nonadjacent to your site.  If \fIx\fR is a domain,
  924. i.e. contains a dot (.), \fBoupath\fR will generate a path to a gateway
  925. for this domain.  Note that \fBoupath\fR will \fInot\fR alter the argument
  926. path, other than to make the above transformations; it does not check whether
  927. sites in the argument are adjacent to one another, or whether they represent
  928. an optimal path; it is assumed that if the user has specified a path, then
  929. he wants to use that path.
  930. .PP
  931. The principal difference between \fBopath\fR and \fBoupath\fR is that the
  932. former gives precedence to ``@'', whereas the latter gives precedence
  933. to ``!''.  The former is intended to be invoked when receiving mail from
  934. a user interface or a non-UUCP source (if the subsequent transport mechanism
  935. is to be UUCP), whereas the latter is intended solely to be used by UUCP
  936. internal software, principally \fBrmail\fR, in routing mail through the
  937. UUCP network.
  938. .SH "FILES"
  939. \fI/usr/lib/uucp/palias\fR - The pathalias database.
  940. See PATHALIAS(1) for information; pathalias is a public-domain program
  941. distributed via the Usenet's net.sources facility.
  942. .br
  943. .sp 1
  944. \fI/usr/lib/uucp/domains\fR - The domain/gateway table.  Each line of this
  945. file consists of either a ``#'' followed by arbitrary comment text, or
  946. an entry of the form:
  947. .br
  948. .in 1i
  949. <domain>,<path>,<reserved>,<template>
  950. .br
  951. .in
  952. Where <domain> is the string (in capital letters) identifying a particular
  953. <path> is a string which may be included at an arbitrary point in the
  954. generated route, <reserved> is currently unused, and <template> is a string
  955. indicating the format of the generated route.
  956. .PP
  957. The <template> is a printf-style string; it is \fBnot\fR quoted, and
  958. begins at the character immediately following the comma which separates
  959. <template> from <reserved>.  The <template> may consist of arbitrary ASCII
  960. characters, which are copied unchanged into the generated route; or of
  961. a percent (%) sign followed by one of the following characters:
  962. .IP P
  963. The <path> string is inserted.  The <path> may consist either of a string
  964. which is inserted unchanged; or of the character ``>'' followed by the
  965. name of a UUCP site, in which case the entire <path> string is replaced
  966. with a string representing the path to the named site.  The last token on
  967. this string is the site named in the original <path> string, without a
  968. following ``!''.
  969. .IP U
  970. The user name from the original address is inserted.
  971. .IP N
  972. The site name from the original address, with the domain specifiers
  973. removed, is inserted.
  974. .IP D
  975. The site name from the original address, including the domain specifiers,
  976. is inserted.
  977. .IP R
  978. The UUCP path to the site named in the original address is looked up in
  979. the pathalias database and inserted.  Note that this path is looked up
  980. only when the %R is seen while scanning the <template>, so an error message
  981. for an invalid site name is generated if and only if it appears in an
  982. address with a domain which contains a %R in its template.
  983. .PP
  984. When making entries in the domain table, domain names which are a suffix of
  985. another domain name in the table should be ordered such that the longer
  986. string(s) appear first.  For example, .WA.UUCP should preceed .UUCP in
  987. the table.  A linear search is made of the table, and the first domain
  988. found in the table which is a suffix of the domain in the designated address
  989. is used as the domain in generating the routing.
  990. .PP
  991. Following are some example entries for the domain table.  Note that all
  992. domain names begin with a ``.''.
  993. .sp 1
  994. .nf
  995. .in 1i
  996. # This is a comment
  997. \&.HP.UUCP,,,%R!%U
  998. \&.UUCP,,,%R!%U
  999. \&.CSNET,>decwrl,,%P!%U%%%S@CSNET-RELAY.ARPA
  1000. \&.EDU,>ucbvax,,%P!%D
  1001. .in
  1002. .fi
  1003. .sp 1
  1004. .SH "SEE ALSO"
  1005. pathalias(1), address(1), rmail(1), uumail(8)
  1006. .SH "AUTHOR"
  1007. Eric Roskos, CONCURRENT COMPUTERS
  1008. .SH "NOTE"
  1009. The <reserved> field in the domain table currently has a function which
  1010. may be determined by examining the source code for opath.  However, this
  1011. function is a vestigal function provided for sites that used an earlier
  1012. version of opath; future opath versions will use this field for a different
  1013. purpose, and new users of opath therefore should \fBnot\fR use this field.
  1014. SHAR_EOF
  1015. if test 4889 -ne "`wc -c < 'opath.3'`"
  1016. then
  1017.     echo shar: error transmitting "'opath.3'" '(should have been 4889 characters)'
  1018. fi
  1019. fi
  1020. echo shar: extracting "'opath.c'" '(5753 characters)'
  1021. if test -f 'opath.c'
  1022. then
  1023.     echo shar: will not over-write existing file "'opath.c'"
  1024. else
  1025. cat << \SHAR_EOF > 'opath.c'
  1026. /*
  1027.  * opath.c - get an optimal uucp path from the path database, using an
  1028.  * RFC882-style address as input.  The '%' character is properly translated,
  1029.  * and gateway-substitution is done to get mail onto other networks.
  1030.  *
  1031.  *
  1032.  * Eric Roskos, Perkin-Elmer Corp. SDC
  1033.  * Version 3.2 created 85/09/12 15:21:51
  1034.  * $Log:    opath.c,v $
  1035.  * Revision 3.7  85/11/14  20:22:16  sob
  1036.  * Added #ifdef DEBUG to allow compiliation without DEBUG
  1037.  * 
  1038.  * Revision 3.6  85/11/08  03:05:22  sob
  1039.  * release version
  1040.  * 
  1041.  * Revision 3.5  85/10/09  03:20:07  sob
  1042.  * Added strindex call to make striping the printf stuff more pleasing.
  1043.  * 
  1044.  * Revision 3.4  85/09/30  02:49:12  sob
  1045.  * Updated to use getpath revised by Stan Barber
  1046.  * 
  1047.  * Revision 3.3  85/09/16  18:32:26  sob
  1048.  * This version will use the getpath subroutine used by uupath/uumail
  1049.  * and is not dependant on whether it is DBM or not.
  1050.  * Also uses the uuconf include file.
  1051.  * 
  1052.  * Revision 3.2  85/09/16  17:50:07  sob
  1053.  * Added to RCS
  1054.  * 
  1055.  */
  1056.  
  1057. static char *opathsccsid = "@(#)opath.c    3.2 (peora) 15:21:51 - 85/09/12";
  1058. static char opathrcsid[] = "$Header: opath.c,v 3.7 85/11/14 20:22:16 sob Exp $";
  1059. #ifdef OPATH
  1060. #include "uuconf.h"
  1061.  
  1062. /**
  1063.  ** User-configurable parameters
  1064.  **/
  1065.  
  1066. /**
  1067.  ** Global Variables
  1068.  **/
  1069.  
  1070. static char pval[150]; /* the path string is built here */
  1071.  
  1072. /*
  1073.  * the following are used to pass results by side-effect from the domain()
  1074.  * routine.
  1075.  */
  1076.  
  1077. static char prefix[80], suffix[80], fullsite[80];
  1078.  
  1079. /**
  1080.  ** Subroutines
  1081.  **/
  1082.  
  1083. /*
  1084.  * The Domain Table and its associated routines
  1085.  */
  1086.  
  1087. static struct domains
  1088. {
  1089.     char dom[50];
  1090.     char pre[50];
  1091.     char suf[50];
  1092.     char map[50];
  1093. } domtab[100];
  1094.  
  1095. /* Inline routine to copy a domain into the domain table */
  1096.  
  1097. #define DOMCPY(fld) { int i = 0; q=dp->fld; while (*p!=','&&*p!='\n'&&*p) \
  1098.             {*q++ = *p++; if (i++>=48) break;} \
  1099.             *q++ = '\0'; if (!*p) { \
  1100.             fprintf(stderr,"opath: fld(s) missing in %s at %s\n", \
  1101.             s, buf); \
  1102.             dp++; continue;} p++; }
  1103.  
  1104. /* Load the domain table from disk */
  1105.  
  1106. static int
  1107. loaddomtab(s)
  1108. char *s;
  1109. {
  1110. FILE *f;
  1111. char buf[100];
  1112. register char *p,*q;
  1113. struct domains *dp;
  1114.  
  1115.     f = fopen(s,"r");
  1116.     if (f==NULL)
  1117.     {
  1118.         fprintf(stderr,"opath: can't open domain file '%s'\n",s);
  1119.         exit(1);
  1120.     }
  1121.  
  1122.     dp = domtab;
  1123.  
  1124.     while (fgets(buf,100,f))
  1125.     {
  1126.         if (buf[0]=='#') continue; /* comments start with "#" */
  1127.         p = buf;
  1128.         DOMCPY(dom);
  1129.         DOMCPY(pre);
  1130.         DOMCPY(suf);
  1131.         DOMCPY(map);
  1132.         if (dp->map[0] == '\0')
  1133.         {
  1134.             fprintf(stderr,"opath: bad route template in %s\n",s);
  1135.             strcpy(dp->map,"Invalid");
  1136.         }
  1137.         dp++;
  1138.     }
  1139.  
  1140.     dp->map[0] = '\0';  /* mark end of table */
  1141.     fclose(f);
  1142.  
  1143.     return(0);
  1144. }
  1145.  
  1146. /* Get a UUCP path from the pathalias database 
  1147.  * and compensate for the format.
  1148.  * Typically the format is
  1149.  * site1!site2!site3!%s to be used in *printf statements.
  1150.  * We don't want the !%s, so we cut it off.
  1151.  * Pretty gross, but it works.
  1152.  */
  1153.  
  1154. static char *
  1155. gpath(s)
  1156. char *s;
  1157. {
  1158. static char path[100];
  1159. int getpath(),x;
  1160.     getpath(s,&path[0],paths);
  1161.         x=strindex(&path[0],"!%s");
  1162.     if (x >0) path[x] = '\0';
  1163. #ifdef DEBUG
  1164.     if (Debug>1)fprintf(stderr,"Getpath returns: %s\n",&path[0]);
  1165. #endif
  1166.     return(&path[0]);
  1167. }
  1168.  
  1169. /* returns location of tx in sx */
  1170. strindex(sx,tx)
  1171. char * sx, *tx;
  1172. {
  1173.     int i,n;
  1174.     n = strlen(tx);
  1175.     for (i=0;sx[i] != '\0'; i++)
  1176.         if (strncmp(sx+i,tx,n) ==0)
  1177.             return(i);
  1178.     return (-1);
  1179. }
  1180.  
  1181. /* String compare: entire first argument must match suffix of 2nd argument */
  1182.  
  1183. static int
  1184. domcmp(ss,tt)
  1185. char *ss, *tt;
  1186. {
  1187. char *s, *t;
  1188. int cmp;
  1189.  
  1190.     s = ss + strlen(ss) - 1;
  1191.     t = tt + strlen(tt) - 1;
  1192.  
  1193.     do
  1194.     {
  1195.         if (*s - *t) break;
  1196.         s--;
  1197.         t--;
  1198.     } while (s >= ss);
  1199.  
  1200.     if (++s == ss) return(0);
  1201.     else return(1);
  1202. }
  1203.  
  1204. /* Look up a domain, and by side effect set prefix and suffix appropriately */
  1205.  
  1206. char *domain(s)
  1207. char *s;
  1208. {
  1209. struct domains *d;
  1210. char *p;
  1211. static int loaded = 0;
  1212.  
  1213.     if (!loaded++) loaddomtab(ConfFile);
  1214.  
  1215.     if (*s!='.') /* default to UUCP domain */
  1216.     {
  1217.         prefix[0]=suffix[0]='\0';
  1218.         return("%R!%U");
  1219.     }
  1220.  
  1221.     for (p=s; *p; p++) if (*p>='a' && *p<='z') *p -= 'a'-'A';
  1222.  
  1223.     for (d = &domtab[0]; (int)d->map[0]; d++)
  1224.     {
  1225.         if (domcmp(d->dom,s)==0) break;
  1226.     }
  1227.  
  1228.     strcpy(prefix,(d->pre[0]=='>')? gpath(&d->pre[1]) : d->pre);
  1229.     strcpy(suffix,d->suf);
  1230.  
  1231.     return(d->map);
  1232. }
  1233.  
  1234. /* opath: generates a UUCP path from an RFC-822 address */
  1235.  
  1236. #define COPYON(s) {char *r; r=s; while (*r) *p++ = *r++; *p = '\0';}
  1237.  
  1238. char *
  1239. opath(s)
  1240. char *s;
  1241. {
  1242. char user[50],site[50];
  1243. static char cm[150];
  1244. FILE *f;
  1245. char *p, *q, *t;
  1246. char *d;
  1247. int i;
  1248. int found;
  1249. char *suf;
  1250.  
  1251.     for (p=user,q=s;(*p = *q)!='@'; p++,q++)
  1252.         if (*q=='\0') return(s);
  1253.     *p = '\0';
  1254.  
  1255.     strcpy(fullsite,++q);
  1256.  
  1257.     for (p=site;(*p = *q)!='.'; p++,q++)
  1258.         if (*q=='\0') break;
  1259.     *p = '\0';
  1260.  
  1261.     d = domain(q);
  1262.  
  1263.     if (d[0]=='\0') return(s); /* unknown domain - do nothing */
  1264.  
  1265.     for (p=pval, q=d; *q; q++)
  1266.     {
  1267.         if (*q=='%')
  1268.         {
  1269.             switch(*++q)
  1270.             {
  1271.             case 'P':
  1272.                 COPYON(prefix);
  1273.                 break;
  1274.  
  1275.             case 'S':
  1276.                 COPYON(suffix);
  1277.                 break;
  1278.  
  1279.             case 'U':
  1280.                 COPYON(user);
  1281.                 break;
  1282.  
  1283.             case 'N':
  1284.                 COPYON(site);
  1285.                 break;
  1286.  
  1287.             case 'D':
  1288.                 COPYON(fullsite);
  1289.                 break;
  1290.  
  1291.             case 'R':
  1292.                 COPYON(gpath(site));
  1293.                 break;
  1294.  
  1295.             case '%':
  1296.                 *p++ = '%';
  1297.                 break;
  1298.             }
  1299.         }
  1300.         else
  1301.             *p++ = *q;
  1302.     }
  1303.  
  1304.     return(pval);
  1305. }
  1306.  
  1307. /* oupath: generates a uucp path from a (possibly disconnected) uucp path */
  1308.  
  1309. char *oupath(s)
  1310. char *s;
  1311. {
  1312. char *p,*q;
  1313. static char adr[100];
  1314. char first[100];
  1315. int found;
  1316.  
  1317.     for (p=s,q=first,found=0; *p!='!' && *p!='\0'; p++)
  1318.     {
  1319.         if (*p=='.') found++;
  1320.         *q++ = *p;
  1321.     }
  1322.     if (*p=='\0') return (s);
  1323.  
  1324.     *q = '\0';
  1325.  
  1326.     if (found)
  1327.     {
  1328.         strcpy(adr,++p);
  1329.         strcat(adr,"@");
  1330.         strcat(adr,first);
  1331.         return(opath(adr));
  1332.     }
  1333.     else
  1334.     {
  1335.     int i;
  1336.         strcpy(adr,gpath(first));
  1337.         strcat(adr,/* ++ */p);
  1338.  
  1339.         return(adr);
  1340.     }
  1341. }
  1342.  
  1343.  
  1344. opathlog(fmt,a,b,c,d)
  1345. char *fmt;
  1346. int a,b,c,d;
  1347. {
  1348. FILE *f;
  1349.  
  1350.     f = fopen(logfile,"a");
  1351.     if (f==NULL) return;
  1352.  
  1353.     fprintf(f,fmt,a,b,c,d);
  1354.     fclose(f);
  1355. }
  1356. #endif
  1357. SHAR_EOF
  1358. if test 5753 -ne "`wc -c < 'opath.c'`"
  1359. then
  1360.     echo shar: error transmitting "'opath.c'" '(should have been 5753 characters)'
  1361. fi
  1362. fi
  1363. echo shar: extracting "'rmail.c'" '(2622 characters)'
  1364. if test -f 'rmail.c'
  1365. then
  1366.     echo shar: will not over-write existing file "'rmail.c'"
  1367. else
  1368. cat << \SHAR_EOF > 'rmail.c'
  1369. #ifndef lint
  1370. static char rcsid[]="$Header: rmail.c,v 1.3 85/11/08 03:05:31 sob RELEASE $";
  1371.  
  1372. #endif
  1373.  
  1374. /*
  1375. **  RMAIL -- UUCP mail server.
  1376. **
  1377. **    This program reads the >From ... remote from ... lines that
  1378. **    UUCP is so fond of and turns them into something reasonable.
  1379. **    It calls uumail giving it a -f option built from these
  1380. **    lines.
  1381. */
  1382.  
  1383. #define _DEFINE
  1384.  
  1385. #include "uuconf.h"
  1386. extern FILE *popen();
  1387. extern char *index();
  1388. extern char *rindex();
  1389.  
  1390. # define MAILER    "/usr/lib/uucp/uumail"
  1391.  
  1392. main(argc, argv)
  1393.     char **argv;
  1394. {
  1395.     FILE *out;    /* output to mail handler */
  1396.     char lbuf[512];    /* one line of the message */
  1397.     char from[512];    /* accumulated path of sender */
  1398.     char ufrom[64];    /* user on remote system */
  1399.     char sys[64];    /* a system in path */
  1400.     char junk[512];    /* scratchpad */
  1401.     char cmd[2000];
  1402.     register char *cp;
  1403.     register char *uf;    /* ptr into ufrom */
  1404.     int i;
  1405.  
  1406. # ifdef DEBUG
  1407.     if (argc > 1 && strcmp(argv[1], "-T") == 0)
  1408.     {
  1409.         Debug = TRUE;
  1410.         argc--;
  1411.         argv++;
  1412.     }
  1413. # endif DEBUG
  1414.  
  1415.     if (argc < 2)
  1416.     {
  1417.         fprintf(stderr, "Usage: rmail user ...\n");
  1418.         exit(EX_USAGE);
  1419.     }
  1420.  
  1421.     (void) strcpy(from, "");
  1422.     (void) strcpy(ufrom, "/dev/null");
  1423.  
  1424.     for (;;)
  1425.     {
  1426.         (void) fgets(lbuf, sizeof lbuf, stdin);
  1427.         if (strncmp(lbuf, "From ", 5) != 0 && strncmp(lbuf, ">From ", 6) != 0)
  1428.             break;
  1429.         (void) sscanf(lbuf, "%s %s", junk, ufrom);
  1430.         cp = lbuf;
  1431.         uf = ufrom;
  1432.         for (;;)
  1433.         {
  1434.             cp = index(cp+1, 'r');
  1435.             if (cp == NULL)
  1436.             {
  1437.                 register char *p = rindex(uf, '!');
  1438.  
  1439.                 if (p != NULL)
  1440.                 {
  1441.                     *p = '\0';
  1442.                     if (uf != NULL) 
  1443.                         (void) strcpy(sys, uf);
  1444.                     else
  1445.                         gethostname(sys,32);
  1446.                     uf = p + 1;
  1447.                     break;
  1448.                 }
  1449.                 cp = "remote from somewhere";
  1450.             }
  1451. #ifdef DEBUG
  1452.             if (Debug)
  1453.                 printf("cp='%s'\n", cp);
  1454. #endif
  1455.             if (strncmp(cp, "remote from ", 12)==0)
  1456.                 break;
  1457.         }
  1458.         if (cp != NULL)
  1459.             (void) sscanf(cp, "remote from %s", sys);
  1460.         (void) strcat(from, sys);
  1461.         (void) strcat(from, "!");
  1462. #ifdef DEBUG
  1463.         if (Debug)
  1464.             printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from);
  1465. #endif
  1466.     }
  1467.     (void) strcat(from, uf);
  1468.  
  1469. /*    (void) sprintf(cmd, "exec %s -em -f%s", MAILER, from);*/
  1470.     (void) sprintf(cmd, "exec %s -f%s", MAILER,from);
  1471.     while (*++argv != NULL)
  1472.     {
  1473.         (void) strcat(cmd, " '");
  1474.         if (**argv == '(')
  1475.             (void) strncat(cmd, *argv + 1, strlen(*argv) - 2);
  1476.         else
  1477.             (void) strcat(cmd, *argv);
  1478.         (void) strcat(cmd, "'");
  1479.     }
  1480. #ifdef DEBUG
  1481.     if (Debug)
  1482.         printf("cmd='%s'\n", cmd);
  1483. #endif
  1484.     out = popen(cmd, "w");
  1485.     fputs(lbuf, out);
  1486.     while (fgets(lbuf, sizeof lbuf, stdin))
  1487.         fputs(lbuf, out);
  1488.     i = pclose(out);
  1489.     if ((i & 0377) != 0)
  1490.     {
  1491.         fprintf(stderr, "pclose: status 0%o\n", i);
  1492.         exit(EX_OSERR);
  1493.     }
  1494.  
  1495.     exit((i >> 8) & 0377);
  1496. }
  1497. SHAR_EOF
  1498. if test 2622 -ne "`wc -c < 'rmail.c'`"
  1499. then
  1500.     echo shar: error transmitting "'rmail.c'" '(should have been 2622 characters)'
  1501. fi
  1502. fi
  1503. echo shar: extracting "'uuconf.h'" '(3241 characters)'
  1504. if test -f 'uuconf.h'
  1505. then
  1506.     echo shar: will not over-write existing file "'uuconf.h'"
  1507. else
  1508. cat << \SHAR_EOF > 'uuconf.h'
  1509. /* $Header: uuconf.h,v 1.5 85/12/10 20:42:30 sob Exp $
  1510.  * Configuration for uumail and uupath utilities
  1511.  * Please see the header for makefile for changes you may
  1512.  * need to make there.
  1513.  * $Log:    uuconf.h,v $
  1514.  * Revision 1.5  85/12/10  20:42:30  sob
  1515.  * Added defines for new parts of getpath, SENTINAL and TIMEOUT
  1516.  * 
  1517.  * Revision 1.4  85/10/02  02:16:21  sob
  1518.  * Added LOCALMAIL definition
  1519.  * 
  1520.  * Revision 1.3  85/09/30  02:50:51  sob
  1521.  * Added pwd.h to list of include files
  1522.  * 
  1523.  * Revision 1.2  85/07/11  19:29:34  sob
  1524.  * *** empty log message ***
  1525.  * 
  1526.  * Revision 1.1  85/07/11  19:22:20  sob
  1527.  * Initial revision
  1528.  * 
  1529.  */
  1530. #include <stdio.h>
  1531. #include <ctype.h>
  1532. #include <pwd.h>
  1533. #include <signal.h>
  1534. #include <setjmp.h>
  1535.  
  1536. /*
  1537.  * sysexits is a file of exit codes that are used in sendmail
  1538.  * and other programs ...
  1539.  */
  1540. #include <sysexits.h>
  1541. /* if you don't have sysexits.h here are the useful parts */
  1542. #ifndef EX_OK
  1543.  
  1544. # define EX_OK        0    /* successful termination */
  1545.  
  1546.  
  1547. # define EX_USAGE    64    /* command line usage error */
  1548. # define EX_DATAERR    65    /* data format error */
  1549. # define EX_NOINPUT    66    /* cannot open input */
  1550. # define EX_NOHOST    68    /* host name unknown */
  1551. # define EX_UNAVAILABLE    69    /* service unavailable */
  1552. # define EX_SOFTWARE    70    /* internal software error */
  1553. # define EX_OSERR    71    /* system error (e.g., can't fork) */
  1554. # define EX_OSFILE    72    /* critical OS file missing */
  1555. # define EX_CANTCREAT    73    /* can't create (user) output file */
  1556. # define EX_IOERR    74    /* input/output error */
  1557. # define EX_TEMPFAIL    75      /* temp failure; user should retry */
  1558. #endif
  1559.  
  1560. typedef char bool;
  1561.  
  1562. #ifdef DBM
  1563. #include <dbm.h>
  1564. #endif
  1565.  
  1566. #ifdef SYSIII
  1567. #define index strchr
  1568. #define rindex strrchr
  1569. #include <sys/utsname.h>
  1570. #endif
  1571.  
  1572. #define NAMESIZ 32 /* system name size */
  1573. #define PATHSIZ 16*NAMESIZ /* path length */
  1574.  
  1575. #define TRUE    1
  1576. #define FALSE    0
  1577.  
  1578. #ifndef TIMEOUT
  1579. #define TIMEOUT ((unsigned) 180)
  1580. #endif TIMEOUT
  1581.  
  1582. #ifndef SENTINEL
  1583. #define SENTINEL "@@@"
  1584. #endif SENTINEL
  1585.  
  1586. /* Here's where you should put in the the name of the file
  1587.  * in which the uucpmap data is kept.
  1588.  * For those using DBM, this will be the root filename for the database
  1589.  * (eg... file.pag and file.dir with root name file)
  1590.  */
  1591.  
  1592. #define DATABASE "/usr/lib/uucp/palias"
  1593. #define CONFIGFILE "/usr/lib/uucp/domains"
  1594. #define LOGFILE "/usr/adm/uumail.log"
  1595. /* this needs to be a printf-like string to deliver LOCAL mail */
  1596. /* usually this is either /bin/mail or /bin/binmail */
  1597.  
  1598. #define LOCALMAIL "/bin/bellmail %s"
  1599.  
  1600. #ifdef _DEFINE
  1601. #define EXTERN 
  1602. #else
  1603. #define EXTERN extern
  1604. #endif
  1605.  
  1606. EXTERN int Debug;
  1607. EXTERN char *paths;
  1608. EXTERN char *ConfFile;
  1609. EXTERN char Myname[NAMESIZ];
  1610. EXTERN char *logfile;
  1611. EXTERN char    OpMode;        /* operation mode, see below */
  1612. /* These don't do anything yet.... next time they will do something */
  1613. #define MD_DELIVER    'm'        /* be a mail sender */
  1614. #define MD_ARPAFTP    'a'        /* old-style arpanet protocols */
  1615. #define MD_SMTP        's'        /* run SMTP on standard input */
  1616. #define MD_DAEMON    'd'        /* run as a daemon */
  1617. #define MD_VERIFY    'v'        /* verify: don't collect or deliver */
  1618. #define MD_TEST        't'        /* test mode: resolve addrs only */
  1619. #define MD_INITALIAS    'i'        /* initialize alias database */
  1620. #define MD_PRINT    'p'        /* print the queue */
  1621. #define MD_FREEZE    'z'        /* freeze the configuration file */
  1622. SHAR_EOF
  1623. if test 3241 -ne "`wc -c < 'uuconf.h'`"
  1624. then
  1625.     echo shar: error transmitting "'uuconf.h'" '(should have been 3241 characters)'
  1626. fi
  1627. fi
  1628. echo shar: extracting "'uumail.1'" '(2280 characters)'
  1629. if test -f 'uumail.1'
  1630. then
  1631.     echo shar: will not over-write existing file "'uumail.1'"
  1632. else
  1633. cat << \SHAR_EOF > 'uumail.1'
  1634. .TH "UUMAIL" "8" "Baylor College of Medicine"
  1635. .fi
  1636. .ad b
  1637. .SH NAME
  1638. uumail \- rewrite address & route mail using uucpmap database 
  1639. .br
  1640. uupath \- print the uucp path to a host
  1641. .SH SYNOPSIS
  1642. .B uumail [ \fIoptions\fR ] \fIaddress\fR
  1643. .br
  1644. .B uupath \fIhostname\fR
  1645. .SH DESCRIPTION
  1646. .B Uumail
  1647. is designed to be used as a mail delivery program to correctly
  1648. route mail over uucp connections.
  1649. .SS Standard Options
  1650. .IP "-f\fIaddress\fR" 16
  1651. The -f option sets the address of the sender of the mail. If this flag 
  1652. is not used, the sender will be established by usings environmental variables
  1653. (like 
  1654. .B LOGNAME
  1655. and
  1656. .B USER
  1657. ) or using getlogin(3).
  1658. .IP "-m" 16
  1659. The -m option causes the mail to also be sent to the sender of the message.
  1660. .IP "-c" 16
  1661. The -c option causes
  1662. .B uucico 
  1663. to be started immediately after queuing the mail.
  1664. The default just queues the mail.
  1665. .IP "-h" 16
  1666. The -h option causes no From_ line to be added to the beginning of file.
  1667. This is useful when uumail is being used as a mailer for sendmail(8).
  1668. .SS Compile-time Configurable Options
  1669. .IP "-d[1-6]" 16
  1670. The -d option turns on the limited debugging facility built into the
  1671. mailer.  In debug mode, the mailer does not actually mail anything, but
  1672. tells you what it would do if it did do it. The level of debugging can
  1673. be set by following the 
  1674. .I -d
  1675. flag with a number between 1 and 6.
  1676. .IP "-g[A-Z]" 16
  1677. If your 
  1678. .B uux(1)
  1679. supports grading of transactions, the -g option can be used to set the
  1680. grade of this mail. A grade of \fIC\fR is used by default.
  1681.  
  1682. .SS Arguments
  1683. .IP \fIhost!user\fR 16
  1684. where host is a system node name on the network and user is the login
  1685. name of the addressee.
  1686. .IP \fIuser@host.domain\fR
  1687. same as above with the addition of a domain specifier like
  1688. .B .ARPA, .GOV, .COM, .EDU
  1689. etc.
  1690. .SH FILES
  1691. .IP "/usr/lib/uucp/palias" 20
  1692. Path file produced by pathalias.
  1693. .IP "/usr/lib/uucp/uucp/domains" 20
  1694. Domain rewriting rules for opath(3).
  1695. .IP "/usr/adm/uumail.log" 20
  1696. Log of uumail activity.
  1697. .SH "SEE ALSO"
  1698. pathalias(1), Pnews(1), Rnmail(1), rn(1), postnews(1), readnews(1),
  1699. opath(3), sendmail(8)
  1700.  
  1701. .SH AUTHORS
  1702. .br
  1703. Stan Barber, Baylor College of Medicine
  1704. .br
  1705. Getpath routine by John Donnelly, University of Illinois
  1706. .br
  1707. Gethostname routine by Peter Honeyman, Princeton
  1708. .br
  1709. Opath routine by Eric Roskos, CONCURRENT Computers
  1710.  
  1711. SHAR_EOF
  1712. if test 2280 -ne "`wc -c < 'uumail.1'`"
  1713. then
  1714.     echo shar: error transmitting "'uumail.1'" '(should have been 2280 characters)'
  1715. fi
  1716. fi
  1717. echo shar: extracting "'uumail.c'" '(12804 characters)'
  1718. if test -f 'uumail.c'
  1719. then
  1720.     echo shar: will not over-write existing file "'uumail.c'"
  1721. else
  1722. cat << \SHAR_EOF > 'uumail.c'
  1723. /*
  1724.  *  U U M A I L
  1725.  *  This program when invoked in the form:
  1726.  *  uumail host!user will consult the local usemap for
  1727.  *  the proper routing.
  1728.  * 
  1729.  *  If it finds it, it will invoke the proper uux call
  1730.  *  to send the mail.
  1731.  *  Otherwise it aborts with an error 68 (host unknown)
  1732.  * $Log:    uumail.c,v $
  1733.  * Revision 2.9  85/12/10  20:36:01  sob
  1734.  * Added new return flag from getpath EX_TEMPFAIL to signal that the
  1735.  * path database is currently being updated.
  1736.  * 
  1737.  * Revision 2.8  85/12/02  16:51:39  sob
  1738.  * Added a fix to cope with percents in addresses returned by opath.
  1739.  * Thank to steve@umd-cs.UUCP for the bug report.
  1740.  * 
  1741.  * Revision 2.7  85/11/18  12:36:48  sob
  1742.  * Added the -h option to cause uumail NOT to add a From_ line.
  1743.  * 
  1744.  * Revision 2.6  85/11/14  20:20:06  sob
  1745.  * Added #ifdef DEBUG to allow compiliation with out DEBUG installed
  1746.  * 
  1747.  * Revision 2.5  85/11/14  20:14:11  sob
  1748.  * Another little buggie in the log format...sheesh.
  1749.  * 
  1750.  * Revision 2.4  85/11/13  15:53:18  sob
  1751.  * Reformated the log file a little bit.
  1752.  * 
  1753.  * Revision 2.3  85/11/08  03:03:51  sob
  1754.  * This is the release version.
  1755.  * 
  1756.  * 
  1757.  * Revision 2.2  85/09/30  02:51:18  sob
  1758.  * This version uses opath when defined during compile time.
  1759.  * With a bit of cleaning up, this is a release version.
  1760.  * 
  1761.  * Revision 2.1  85/09/30  02:46:06  sob
  1762.  * *** empty log message ***
  1763.  * 
  1764.  * Revision 2.0  85/09/09  18:22:56  UUCP
  1765.  * *** empty log message ***
  1766.  * 
  1767.  * Revision 2.0  85/09/09  18:22:56  UUCP
  1768.  * Added flags to conform with sendmail. Also updated the flags it could send
  1769.  * to uux to conform with 4.3 uux command.
  1770.  * Will add name resolution and header checking.
  1771.  * Also will allow multiple addresses per line.
  1772.  * 
  1773.  * Revision 1.7  85/08/03  00:49:14  UUCP
  1774.  * Cleaned up with lint.
  1775.  * Stan Barber
  1776.  * 
  1777.  * Revision 1.6  85/07/11  19:30:00  sob
  1778.  * changed PATHSIZE to PATHSIZ to conform with uupath
  1779.  * 
  1780.  * Revision 1.5  85/07/11  18:08:13  sob
  1781.  * This one works both as uumail and uupath!
  1782.  * Stan
  1783.  * 
  1784.  * Revision 1.4  85/07/10  18:35:05  sob
  1785.  * moved DBM to getpath
  1786.  * Stan Barber
  1787.  * 
  1788.  * Revision 1.3  85/07/09  01:28:14  sob
  1789.  * First attempt to integrate uupath
  1790.  * Not successful. Changed PATHALIAS define
  1791.  * to DBM... will ultimately alter getpath as well
  1792.  * added gethostname call to fill in for local host.
  1793.  * 
  1794.  * Revision 1.2  85/07/08  05:29:16  sob
  1795.  * This one works with pathalias database...
  1796.  * need to modify to substitue for uupath.
  1797.  * Stan
  1798.  * 
  1799.  * Revision 1.1  85/07/08  03:11:10  sob
  1800.  * Initial revision
  1801.  * 
  1802.  */
  1803. #define _DEFINE
  1804.  
  1805. #include "uuconf.h"
  1806.  
  1807.  
  1808. EXTERN bool uupath;
  1809. extern int      errno;
  1810. extern struct passwd *getpwuid();
  1811. extern FILE    *popen();
  1812. extern char     *ctime();
  1813. extern char    *getlogin();
  1814. extern char    *index();
  1815. extern char    *rindex();
  1816. extern char    *malloc();
  1817. extern char     *getenv();
  1818. EXTERN char    progname[12];
  1819. EXTERN char  *paths;
  1820. int local;
  1821. char templet[64];
  1822. char * from;
  1823.  
  1824.  
  1825. static char Version[] ="$Header: uumail.c,v 2.9 85/12/10 20:36:01 sob Exp $";
  1826.  
  1827. main(argc, argv)
  1828.     char **argv;
  1829. {
  1830.     FILE *out, *tmpf;    /* output to uux, temp file */
  1831.     char lbuf[512]; /* for pipe to uux */
  1832.     char sender[512];    /* accumulated path of sender */
  1833.     char sys[64];    /* a system in path */
  1834.     char cmd[2000];
  1835.     char **av;
  1836.     int i,
  1837.             error = 0,
  1838.             bangcnt, hopcount = 30,
  1839.         metoo=0, noheader = 0,
  1840.         startuux ;
  1841.         
  1842.     char    c,
  1843.             grade = 'C',
  1844.        name[20],             /* The system name (if any) */
  1845.        *fname,
  1846.        *path,            /* uupath to the system */
  1847.            *sysname,            /* points to the system name */
  1848.            *p, *q, *r,            /* tmp pointer to argv's */
  1849.        *rsys,
  1850.        *FullName;
  1851.        bool GrabTo,safecf,NoAlias;
  1852.        extern intsig();
  1853.  
  1854.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  1855.         (void) signal(SIGINT, intsig);
  1856.     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
  1857.         (void) signal(SIGHUP, intsig);
  1858.     (void) signal(SIGTERM, intsig);
  1859.     (void) signal(SIGPIPE, SIG_IGN);
  1860.  
  1861.  
  1862.     for (i = 3; i < 20; i++)
  1863.         (void) close(i);
  1864.     errno = 0;
  1865.     gethostname(Myname,32);
  1866.     paths=DATABASE;
  1867.     logfile=LOGFILE;
  1868.     argv[argc] = NULL;
  1869.     av = argv;
  1870.     p = rindex(*av, '/');
  1871.     if (p++ == NULL)
  1872.         p = *av;
  1873.     strcpy(progname ,p);
  1874.     if(strcmp(p,"uupath") == 0)
  1875.         uupath = TRUE;
  1876.     while ((p = *++av) != NULL && p[0] == '-')
  1877.     {
  1878.         switch (p[1])
  1879.         {
  1880.  
  1881.           case 'C':    /* select configuration file */
  1882.             ConfFile = &p[2];
  1883.             safecf = FALSE;
  1884.  
  1885.             break;
  1886.  
  1887.           case 'g':   /* set grade */
  1888.             grade = p[2];
  1889.             break;
  1890.     
  1891. # ifdef DEBUG
  1892.           case 'd':    /* debug */
  1893.             Debug= atoi(&p[2]);
  1894.             if (Debug == 0) Debug = 1;
  1895.             setbuf(stdout, (char *) NULL);
  1896.             printf("Version %s\n", Version);
  1897.             break;
  1898. # endif DEBUG
  1899.  
  1900.           case 'f':    /* from address */
  1901.           case 'r':    /* obsolete -f flag */
  1902.             p += 2;
  1903.             if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
  1904.             {
  1905.                 p = *++av;
  1906.                 if (p == NULL || *p == '-')
  1907.                 {
  1908.                     syserr("No \"from\" person");
  1909.                     av--;
  1910.                     break;
  1911.                 }
  1912.             }
  1913.             if (from != NULL)
  1914.             {
  1915.                 syserr("More than one \"from\" person");
  1916.                 break;
  1917.             }
  1918.             from = p;
  1919.             break;
  1920.  
  1921.           case 'w':    /* just print the path */
  1922.             uupath = TRUE;
  1923.             break;
  1924.           case 'm':    /* send to me too */
  1925.             metoo = TRUE;
  1926.             break;
  1927.           case 'c':    /* connect to non-local mailers */
  1928.             startuux= TRUE;
  1929.             break;
  1930.           case 'h':    /* don't add a From line */
  1931.             noheader = TRUE;
  1932.             break;
  1933.             }
  1934.     
  1935.         }
  1936.  
  1937.     if(*av==NULL && GrabTo!= TRUE)
  1938.     {
  1939.         fprintf(stderr,"Usage: %s [flags] address\n",progname);
  1940.         exit(EX_USAGE);
  1941.     }
  1942.  
  1943.     if (ConfFile == NULL) ConfFile = CONFIGFILE;
  1944.  
  1945.     if(from==NULL || strlen(from) == 0){
  1946.         if (((from = getenv("LOGNAME")) == NULL) || (strlen(from) == 0))
  1947.             from = getenv("USER");
  1948.         if ((from == NULL) || (strlen(from) == 0))
  1949.             from = getlogin();
  1950.         if ((from == NULL) || (strlen(from) == 0))
  1951.             from = getpwuid(geteuid())->pw_name;
  1952.     }
  1953.  
  1954. if (!uupath)
  1955. {    
  1956. #ifdef DEBUG
  1957.     if (Debug) printf("Mail from %s\n",from);
  1958. #endif
  1959.     /*
  1960.      * Make temporary file for letter
  1961.      * (I wish ACCESS(2) would take care of this better !!)
  1962.      */
  1963.     if ((p=getenv("HOME"))== NULL)
  1964.         p="/tmp";
  1965.     sprintf(&templet[0],"%s/.uumXXXXXX",p);
  1966.     mktemp(templet);
  1967.     unlink(templet);
  1968.     if ((i=open(templet,2)) < 0)
  1969.         {
  1970.             p="/tmp";
  1971.     
  1972.             sprintf(&templet[0],"%s/.uumXXXXXX",p);
  1973.             mktemp(templet);
  1974.             unlink(templet);
  1975.         }
  1976.     else
  1977.         {
  1978.             close(i);
  1979.             unlink(templet);
  1980.         }
  1981. #ifdef DEBUG
  1982.     if (Debug>2) printf("Temp file is %s\n",templet);
  1983. #endif
  1984.     if((tmpf = fopen(templet, "w")) == NULL){
  1985.         fprintf(stderr, "%s : can't open %s for writing\n", progname,templet);
  1986.         fclose(stdin);
  1987.         exit(EX_CANTCREAT);
  1988.  
  1989.         }
  1990.     while(fgets(lbuf,sizeof lbuf,stdin))
  1991.         fputs(lbuf,tmpf);
  1992.     fclose(tmpf);
  1993.     fclose(stdin);
  1994. /* file now saved */
  1995.     if((tmpf = fopen(templet, "r")) == NULL){
  1996.         fprintf(stderr, "%s : can't open %s for reading\n", progname,templet);
  1997.         exit(EX_OSERR);
  1998.     }
  1999.     
  2000. }    
  2001.     (void) strcpy(sender, "");
  2002.  
  2003.     path = malloc(PATHSIZ);
  2004.  
  2005.     av--;
  2006.  
  2007.     if(metoo)
  2008.     {
  2009.     *av = from;
  2010.     av --;
  2011.     }
  2012.     
  2013.     while (av++ != NULL && *av != NULL)
  2014.     {
  2015.     local = bangcnt = 0;
  2016.     
  2017.     
  2018.     q = p = *av;
  2019.     
  2020.     sysname = &name[0];
  2021.  
  2022.     
  2023.     if (uupath) 
  2024.  
  2025.     {
  2026.     (void) strcpy(sysname ,p);
  2027. #ifdef OPATH
  2028.     if ((error = getpath (&name[0], path,paths)) != EX_OK)
  2029.         {
  2030.         if (error == EX_NOHOST) fprintf (stderr, "System %s not found in network map\n", &name[0]);
  2031.         if (error == EX_NOINPUT) fprintf(stderr,"Database %s could not be opened\n",paths);
  2032.         if (error == EX_TEMPFAIL) fprintf(stderr,"Database %s is being updated\nTry again later.\n",paths);
  2033.         exit(EX_NOHOST);
  2034.         }
  2035.     }
  2036.     else 
  2037.     if (index(p,'@') == NULL) strcpy(path,oupath(p)); 
  2038.         else strcpy(path,opath(p));
  2039.  
  2040. /* fix string to allow % to be untranslated by printf and 
  2041.  * friends 
  2042.  */
  2043.    if ((r=index(path,'%')) != NULL)
  2044.     {
  2045.         char t[PATHSIZ];
  2046.         strncpy(t,path,(r-path));
  2047.         strcat(t,"%");
  2048.         strcat(t,r);
  2049.         path = &t[0];
  2050. #ifdef DEBUG
  2051.     if (Debug>3)
  2052.         fprintf(stderr,"In percent fix, %s\n",t);
  2053. #endif
  2054.     }
  2055.  
  2056.  
  2057.  
  2058.  
  2059. #ifdef DEBUG
  2060.     if (Debug >1) fprintf(stderr,"Opath returns %s\n",path);
  2061. #endif
  2062.  
  2063.     if (path[0] == '!')  /* no match in pathalias database */
  2064.     {
  2065.         deadletter(tmpf,local);
  2066.         unlink(templet);
  2067.         exit(EX_NOHOST);
  2068.     }
  2069.    
  2070.    if (strcmp(path,p) == 0)
  2071.     {
  2072.     strcpy(path,Myname);
  2073.     local = 1;
  2074.     }
  2075.  
  2076. #else
  2077.     }
  2078.     else
  2079. {
  2080.     do                        /* count bangs */
  2081.         {
  2082.             while (((c = *p++) != '!') && (c != '\0'));
  2083.                 if (c == '!') bangcnt++;
  2084.         }
  2085.     while (c != '\0' && bangcnt == 1);
  2086.         ;
  2087.     if (bangcnt >= 1)                /* expand path */
  2088.         {
  2089.             while ((*sysname++ = *q++) != '!');
  2090.                 *--sysname = '\0';
  2091.  
  2092.             }
  2093.     /* insert code here to look at uucp neighbors & local host */
  2094.     if (bangcnt == 0) {
  2095.             strcpy(sysname,Myname);
  2096.             local = 1;
  2097.             }
  2098.     }
  2099. #ifdef DEBUG
  2100.     if (Debug>1) printf("sysname = %s\n",&name[0]);
  2101. #endif
  2102.     
  2103.     if (!local && (error = getpath (&name[0], path,paths)) != EX_OK)
  2104.         {
  2105.         if (error == EX_NOHOST) fprintf (stderr, "System %s not found in network map\n", &name[0]);
  2106.         if (error == EX_NOINPUT) fprintf(stderr,"Database %s could not be opened\n",paths);
  2107.         if (error == EX_TEMPFAIL) fprintf(stderr,"Database %s is being updated\nTry again later.\n",paths);
  2108.         exit(EX_NOHOST);
  2109.         }
  2110.  
  2111.        if (local) path = sysname;
  2112. #endif
  2113.  
  2114.  
  2115. #ifdef DEBUG
  2116.        if(Debug>1) printf("Path = %s\n",path);
  2117. #endif
  2118.  
  2119.     p = q;                    /* save name */
  2120.     for (i = 0; i < 1 && *p != '\0'; p++)
  2121.         if (*p == '/')
  2122.         i++;
  2123.     fname = &sender[0];
  2124.  
  2125.         if (uupath)
  2126.         sprintf(fname,path,"username");
  2127.     else
  2128.         sprintf(fname,path,q);
  2129.  
  2130.     p = &sender[0];
  2131.     rsys = &sys[0];
  2132.  
  2133.     if (!local)
  2134.         {
  2135.         while((*rsys++ = *p++) != '!');
  2136.         *--rsys = '\0';
  2137.         }
  2138.         else
  2139. /* local host, remove @ sign */
  2140.         {
  2141.         strcpy(rsys,*av);
  2142.         q=rsys;
  2143.         if (index(rsys,'@') != 0)
  2144.             { 
  2145.                 while (*q++ !='@');
  2146.                 *--q='\0';
  2147.             }
  2148.         /* assume that if it has a bang in it uux
  2149.             will either reject it or know what to do with it */
  2150.         /* this is a little gross */
  2151.         if ((q = index(rsys,'!')) != 0)
  2152.             {
  2153.             local=0;
  2154.             strcpy(&sys[0],rsys);
  2155.             sys[q-rsys]='\0';
  2156.             p=q+1;
  2157.             }
  2158.     }
  2159.         
  2160.     if ((!local && *fname =='\0') || (local && &sys[0]=='\0')) {
  2161.         fprintf(stdout, "null name\n");
  2162.         exit(EX_DATAERR);
  2163.     }
  2164. #ifdef DEBUG
  2165.     if (Debug>3)
  2166.         printf("p = %s sys = %s fname = %s\n",p, &sys[0],fname);
  2167. #endif
  2168.  
  2169.     if (uupath)
  2170.         {
  2171.         printf ("Path to %s:  %s\n", *av, fname);
  2172.         continue;
  2173.         }
  2174.     else
  2175.     {
  2176.         if (local)
  2177.             sprintf(cmd, LOCALMAIL, &sys[0]);
  2178.         else {
  2179.             strcpy(cmd,"uux - ");
  2180.         if (!startuux)
  2181.             strcat(cmd,"-r");
  2182. #ifndef NORETURN
  2183.         if (from)
  2184.             {
  2185.             strcat(cmd," -a");
  2186.             strcat(cmd,from);
  2187.             }
  2188. #endif
  2189. #ifndef NOGRADE
  2190.         if (grade)
  2191.             {
  2192.             char work[10];
  2193.             sprintf(work," -g%c",grade);
  2194.             strcat(cmd,work);
  2195.             }
  2196. #endif        
  2197.         if (index(p, '!'))
  2198.             {
  2199.                 char work[100];
  2200.                 sprintf(work, " %s!rmail \\(%s\\)",  &sys[0], p);
  2201.                 strcat(cmd,work);
  2202.             }
  2203.         else
  2204.             {
  2205.                 char work[100];
  2206.                 sprintf(work, " %s!rmail %s", &sys[0], p);
  2207.                 strcat(cmd,work);
  2208.             }
  2209.         }
  2210. #ifdef DEBUG
  2211.     if (Debug) fprintf(stderr,"Command is %s\n",cmd);
  2212. #endif
  2213.         rewind(tmpf);
  2214. #ifdef DEBUG
  2215.         if (Debug)
  2216.             out = fopen("UUMAIL.TEST","w");
  2217.         else
  2218. #endif
  2219.             out = popen(cmd, "w");
  2220. /*        fputs(lbuf, out); */
  2221.         if (!noheader) Putfrom(tmpf,out);
  2222.         while (fgets(lbuf, sizeof lbuf, tmpf))
  2223.             fputs(lbuf, out);
  2224.  
  2225. /* may not be needed */
  2226.         if (local)
  2227.             fprintf(out,"\n.\n");
  2228.  
  2229. #ifdef DEBUG
  2230.         if (Debug)
  2231.             i = fclose(out);
  2232.         else
  2233. #endif
  2234.             i = pclose(out);
  2235.         if ((i & 0377) != 0)
  2236.             {
  2237.                 fprintf(stderr, "pclose: status 0%o\n", i);
  2238.                 deadletter(tmpf,local);
  2239. #ifdef DEBUG
  2240.                 if (Debug <3) unlink(templet);
  2241. #endif
  2242.                 exit(EX_OSERR);
  2243.             }
  2244. #ifdef LOG
  2245.         maillog(cmd);
  2246. #endif
  2247.        }
  2248.     }
  2249. #ifdef DEBUG
  2250.     if (Debug <3) unlink(templet);
  2251. #endif
  2252. exit(EX_OK);
  2253. }
  2254.  
  2255. /* print an error message on stderr */
  2256.  
  2257. syserr(string)
  2258. char * string;
  2259. {
  2260.     fprintf(stderr,"%s\n",string);
  2261. }
  2262.  
  2263. /* make a unix type From line and send it out the stream */
  2264.  
  2265. Putfrom(into,outto)
  2266. FILE *into, *outto;
  2267. {
  2268.     char    *asctime();
  2269.     struct    tm *bp, *localtime();
  2270.     char    *tp, *zp;
  2271.     int    n,fromflag=0;
  2272.     char buf[128];
  2273.     long iop;
  2274.  
  2275.     /*
  2276.      * Format time
  2277.      */
  2278.     time(&iop);
  2279.     bp = localtime(&iop);
  2280.     tp = asctime(bp);
  2281. /*    zp = tzname[bp->tm_isdst];*/
  2282. /*    sprintf(buf, "%s%s %.16s %.3s %.5s", from, tp, zp, tp+20);*/
  2283.     sprintf(buf, "From %s %.16s %.4s", from, tp, tp+20);
  2284.  
  2285. #ifdef UGLYUUCP
  2286.     if (!local){
  2287.             strcat(buf," remote from ");
  2288.             strcat(buf,Myname);
  2289.            }
  2290. #endif
  2291.     strcat(buf,"\n");
  2292.     write(outto->_file,buf,strlen(buf));
  2293.     fflush(outto);
  2294.  
  2295.     if (fgets(buf,sizeof(buf),into) != NULL)
  2296.     if((strncmp(&buf[0], "From ", 5) == 0 || strncmp(&buf[0], "From:", 5) == 0))
  2297.          write(outto->_file,">",1);
  2298.     
  2299.     write(outto->_file,buf,strlen(buf));
  2300. }
  2301.  
  2302.  
  2303. /* attempt to return dead letter */
  2304. /* we'll do better on this one next time */
  2305.  
  2306. deadletter(retlet, here)
  2307. FILE *retlet;
  2308. int here;
  2309. {
  2310.     if(getlogin() != NULL) syserr("Letter failed....\n");
  2311. }
  2312.  
  2313. /* go here on a signal we want to catch */
  2314. intsig()
  2315. {
  2316.     unlink(templet);
  2317.     exit(EX_OK);
  2318. }
  2319.  
  2320. /* put command strings in the logfile */
  2321.  
  2322. #ifdef LOG
  2323.  
  2324. maillog(command)
  2325. char * command;
  2326. {
  2327.     FILE *f;
  2328.     char atime[24];
  2329.     long clock;
  2330.     time (&clock);
  2331.     strncpy(atime,ctime(&clock),24);
  2332.  
  2333.     if ((f=fopen(logfile,"a")) != NULL)
  2334.         {
  2335.             fprintf(f,"%s: %s - %s\n",progname,atime,command);
  2336.             fclose(f);
  2337.         }
  2338. }
  2339.  
  2340. #endif
  2341. SHAR_EOF
  2342. if test 12804 -ne "`wc -c < 'uumail.c'`"
  2343. then
  2344.     echo shar: error transmitting "'uumail.c'" '(should have been 12804 characters)'
  2345. fi
  2346. fi
  2347. echo shar: extracting "'uupath.1'" '(759 characters)'
  2348. if test -f 'uupath.1'
  2349. then
  2350.     echo shar: will not over-write existing file "'uupath.1'"
  2351. else
  2352. cat << \SHAR_EOF > 'uupath.1'
  2353. .TH "UUPATH" "1" "Baylor College of Medicine"
  2354. .fi
  2355. .ad b
  2356. .SH NAME
  2357. uupath \- print mail routing information using uucpmap database
  2358. .SH SYNOPSIS
  2359. .B uupath  \fIhost1 host2 host3 ...\fR
  2360. .SH DESCRIPTION
  2361. .B Uupath
  2362. is designed to be used to query the uucpmap database for mail routing
  2363. paths used by
  2364. .I uumail.
  2365. .SS Arguments
  2366. .IP "host1 host2 host3 ..."
  2367. where host1, host2, host3 and so on are system node names on the network.
  2368. Many hostnames may be entered as arguements to
  2369. .I uupath.
  2370.  
  2371. .SH FILES
  2372. .IP "/usr/lib/uucp/palias" 
  2373. Path file produced by pathalias.
  2374. .SH "SEE ALSO"
  2375. pathalias(1), Pnews(1), Rnmail(1), rn(1), postnews(1), readnews(1), uumail(8)
  2376.  
  2377. .SH AUTHORS
  2378. .br
  2379. Jeff Donnelly, University of Illinois
  2380. .br
  2381. Stan Barber, Baylor College of Medicine & Rice University
  2382.  
  2383. SHAR_EOF
  2384. if test 759 -ne "`wc -c < 'uupath.1'`"
  2385. then
  2386.     echo shar: error transmitting "'uupath.1'" '(should have been 759 characters)'
  2387. fi
  2388. fi
  2389. echo shar: extracting "'uupath.c'" '(1155 characters)'
  2390. if test -f 'uupath.c'
  2391. then
  2392.     echo shar: will not over-write existing file "'uupath.c'"
  2393. else
  2394. cat << \SHAR_EOF > 'uupath.c'
  2395. /*
  2396.  * Name: uupath
  2397.  *
  2398.  * Calls getpath to lookup the usenet path
  2399.  *
  2400.  * Author: J. Donnelly  3/82
  2401.  * $Log:    uupath.c,v $
  2402.  * Revision 1.3  85/08/03  01:26:17  UUCP
  2403.  * *** empty log message ***
  2404.  * 
  2405.  * Revision 1.2  85/07/19  17:47:05  UUCP
  2406.  * updated to define Debug for compatability with getpath
  2407.  * 
  2408.  * Revision 1.1  85/07/11  18:35:59  sob
  2409.  * Initial revision
  2410.  * 
  2411.  *
  2412.  */
  2413.  
  2414. #include    "uuconf.h"
  2415. bool Debug;
  2416.  
  2417. static char rcsid[] = "$Header: uupath.c,v 1.3 85/08/03 01:26:17 UUCP Exp $";
  2418.  
  2419. main (argc, argv) char *argv[];
  2420. {
  2421.     char    path[PATHSIZ],work[BUFSIZ];
  2422.     int     i,
  2423.             retval;                    /* value returned from getpath */
  2424.  
  2425.     if (argc < 2)
  2426.     {
  2427.     printf ("Usage: uupath sysname1 sysname2 ...\n");
  2428.     exit (EX_USAGE);
  2429.     }
  2430.  
  2431.     for (i = 1; i < argc; i++)
  2432.     {
  2433.     retval = getpath (argv[i], &path[0],DATABASE);        /* lookup usenet path */
  2434.     if (retval == EX_NOHOST)
  2435.         printf ("Can't find path to %s\n", argv[i]);
  2436.  
  2437.     else
  2438.         if (retval == EX_NOINPUT)
  2439.         {
  2440.         printf ("Can't open the network map\n");
  2441.         exit (EX_TEMPFAIL);
  2442.         }
  2443.  
  2444.         else
  2445.         {
  2446.         sprintf (&work[0],"Path to %s:  %s\n", argv[i], &path[0]);
  2447.             printf(&work[0],"username");
  2448.         }
  2449.     }
  2450. }
  2451. SHAR_EOF
  2452. if test 1155 -ne "`wc -c < 'uupath.c'`"
  2453. then
  2454.     echo shar: error transmitting "'uupath.c'" '(should have been 1155 characters)'
  2455. fi
  2456. fi
  2457. exit 0
  2458. #    End of shell archive
  2459.